package com.qtenv.datasync.base;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.qtenv.datasync.api.degao.DeGaoApi;
import com.qtenv.datasync.constant.AppConstants;
import com.qtenv.datasync.service.entity.TerminalHistoryData;
import com.qtenv.datasync.service.entity.Terminals;
import com.qtenv.datasync.service.entity.Terminals_bf;
import com.qtenv.datasync.service.entity.degao.DGTerminalHistoryData;
import com.qtenv.datasync.service.service.TerminalHistoryDataService;
import com.qtenv.datasync.service.service.TerminalsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName DataSyncer
 * @Author CBL
 * @Date 2022/2/24 10:28
 **/
@Component
public abstract class DataSyncer {
    @Autowired
    private TerminalHistoryDataService terminalHistoryDataService;
    @Autowired
    private TerminalsService terminalsService;

    /**
     * 厂家名称
     */
    private String supplier;

    public DataSyncer() {
    }

    public DataSyncer(String supplier) {
        this.supplier = supplier;
    }

    /**
     * 获取厂家历史数据
     *
     * @param tenantId     租户ID
     * @param strStartTime 开始时间
     * @param strEndTime   结束时间
     * @return
     */
    public abstract List<TerminalHistoryData> getTerminalHistoryData(String tenantId, String strStartTime, String strEndTime);

    public List<TerminalHistoryData> getTerminalHistoryDataForTerminal(Terminals_bf terminals, String tenantId, String strStartTime, String strEndTime){
        if(terminals.getSupplierID() != null && 1002 == terminals.getSupplierID()){
            String tids = "";
            if("551175".equals(tenantId)){
                //用备注
                tids = terminals.getReMark();
            }else{
                tids = terminals.getTerminalID().substring(10);
            }
            return this.doGetTerminalHistoryDataFromTerminal(terminals,tenantId, tids, strStartTime, strEndTime);
        }else {
            return null;
        }
    }

    public List<TerminalHistoryData> doGetTerminalHistoryDataFromTerminal(Terminals_bf terminals, String tenantId, String tids, String strStartTime, String strEndTime) {
        String strBegin = strStartTime.replace(" ","T");
        String strEnd = strEndTime.replace(" ","T");

        String dataStr = DeGaoApi.GetScadaValueByUserTerminals(tids, strBegin, strEnd);
        List<TerminalHistoryData> dataEntities = this.transformFromTerminal(terminals,tenantId, dataStr);
        if (CollectionUtil.isEmpty(dataEntities)) {
            System.out.println(String.format("大表【%s】当天暂无数据需要同步", tids));
        } else {
            return dataEntities;
        }

        return null;
    }
    public List<TerminalHistoryData> transformFromTerminal(Terminals_bf terminals, String tenantId, String strData) {
        List<TerminalHistoryData> result = CollectionUtil.newArrayList();

        JSONArray jsonArray = JSON.parseArray(strData);
        if (CollectionUtil.isNotEmpty(jsonArray)) {
            jsonArray.forEach(json -> {
                JSONObject jsonObject = JSON.parseObject(json.toString());
                String terminalID = jsonObject.getString("Id");
                JSONArray dataArray = JSON.parseArray(jsonObject.getString("Data"));
                dataArray.forEach(dataJson -> {
                    JSONObject dataJsonObject = JSON.parseObject(dataJson.toString());
                    Date readDate = DateUtil.parse(dataJsonObject.getString("Time"), DatePattern.NORM_DATETIME_FORMAT);
                    DGTerminalHistoryData dgTerminalHistoryData = JSON.parseObject(dataJsonObject.getString("Value"), DGTerminalHistoryData.class);

                    TerminalHistoryData terminalHistoryData = new TerminalHistoryData();
                    BeanUtil.copyProperties(dgTerminalHistoryData, terminalHistoryData);
                    terminalHistoryData.setTenant_id(tenantId);
                    terminalHistoryData.setSupplierID(AppConstants.DG_SUPPLIER_ID);
                    terminalHistoryData.setTerminalID(terminals.getTerminalID());
                    terminalHistoryData.setReadDate(readDate);
                    terminalHistoryData.setReadDate_s(readDate);
                    result.add(terminalHistoryData);
                });
            });
        }

        return result;
    }
    /**
     * 获取厂家历史数据
     *
     * @param tenantId       租户ID
     * @param terminalIdList 设备ID列表
     * @param strStartTime   开始时间
     * @param strEndTime     结束时间
     * @return
     */
    public abstract List<TerminalHistoryData> getTerminalHistoryData(String tenantId, List<String> terminalIdList, String strStartTime, String strEndTime);

    /**
     * 将厂家历史数据同步到数据库
     *
     * @param tenantId       租户ID
     * @param terminalIdList 设备ID列表
     * @param strStartTime   开始时间
     * @param strEndTime     结束时间
     */
    public void syncTerminalHistoryData(String tenantId, List<String> terminalIdList, String strStartTime, String strEndTime) {
        System.out.println("开始时间：" + strStartTime + "=====结束时间：" + strEndTime);
        List<TerminalHistoryData> historyDataList = this.getTerminalHistoryData(tenantId, terminalIdList, strStartTime, strEndTime);
        this.syncToDb(historyDataList, strStartTime, strEndTime);
    }

    /**
     * 将厂家历史数据同步到数据库
     *
     * @param tenantId     租户ID
     * @param strStartTime 开始时间
     * @param strEndTime   结束时间
     */
    public void syncTerminalHistoryData(Integer supplierId, String tenantId, String strStartTime, String strEndTime) {
        System.out.println("开始时间：" + strStartTime + "=====结束时间：" + strEndTime);
        //更改为一个设备请求一次
        List<TerminalHistoryData> historyDataList = new ArrayList<>();
        List<Terminals_bf> terminalsList = terminalsService.findMasTerminalsByTenantAndSupplier_new(tenantId, supplierId);
        terminalsList.forEach(e->{
            List<TerminalHistoryData> tt = this.getTerminalHistoryDataForTerminal(e,tenantId, strStartTime, strEndTime);
            if(tt != null && !tt.isEmpty()) {
                historyDataList.addAll(tt);
            }
        });

        if(!historyDataList.isEmpty()){
            this.syncToDb(historyDataList, strStartTime, strEndTime);
        }

    }

    /**
     * 将厂家历史数据同步到数据库
     *
     * @param tenantId     租户ID
     * @param supplierId 厂家编号
     */
    public void syncTerminalHistoryData(Integer supplierId, String tenantId) {
        String startTime = DateUtil.now().substring(0, 10)+" 00:00:00";
        String endTime = DateUtil.now().substring(0, 10)+" 23:59:59";
        String tempStartTime;
        //更改为一个设备请求一次
        List<TerminalHistoryData> historyDataList = new ArrayList<>();
        List<Terminals_bf> terminalsList = terminalsService.findMasTerminalsByTenantAndSupplierAndLastTime(tenantId, supplierId);

        List<Date> lastDateList = terminalsList.stream().map(Terminals_bf::getLastTime).filter(Objects::nonNull).collect(Collectors.toList());
        if(!lastDateList.isEmpty()) {
            Optional<Date> opt = lastDateList.stream().min(Comparator.comparing(Date::getTime));
            tempStartTime = DateUtil.format(opt.get(),"yyyy-MM-dd HH:mm:ss");
        } else {
            tempStartTime = startTime;
        }
        terminalsList.forEach(e->{
//            String newStartTime = e.getLastTime()!=null ? DateUtil.format(DateUtil.offsetMinute(e.getLastTime(),1) ,"yyyy-MM-dd HH:mm:ss") : startTime;
            List<TerminalHistoryData> tt = this.getTerminalHistoryDataForTerminal(e,tenantId, tempStartTime, endTime);
            if(tt != null && !tt.isEmpty()) {
                historyDataList.addAll(tt);
            }
        });
        if(!historyDataList.isEmpty()){
            this.syncToDb(historyDataList, tempStartTime, endTime);
        }
    }

    public void syncToDb(List<TerminalHistoryData> historyDataList, String strStartTime, String strEndTime) {
        if (CollectionUtil.isNotEmpty(historyDataList)) {
            try {
                List<TerminalHistoryData> records = terminalHistoryDataService.findRecords(strStartTime, strEndTime);
                if (CollectionUtil.isNotEmpty(records)) {
                    records.forEach(item -> historyDataList.removeIf(data -> data.getTerminalID().equals(item.getTerminalID()) && data.getReadDate().equals(item.getReadDate())));
                }

                if (CollectionUtil.isNotEmpty(historyDataList)) {
                    System.out.println("从厂家：【" + this.supplier + "】获取的历史数据总量：" + historyDataList.size() + "条");
                    long start = System.currentTimeMillis();
//                    System.out.println(JSON.toJSONString(historyDataList));
                    terminalHistoryDataService.saveToMiddle(historyDataList);
                    System.out.println("厂家：【" + this.supplier + "】历史数据同步成功，本次同步了【" + historyDataList.size() + "】条数据，耗时：" + (System.currentTimeMillis() - start) / 1000.0 + "秒");
                } else {
                    System.out.println("厂家：【" + this.supplier + "】暂无历史数据需要同步！");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("厂家：【" + this.supplier + "】暂无历史数据需要同步！");
        }
        System.out.println("=====厂家：【" + this.supplier + "】数据同步任务完成！=====");
    }


    /**
     * @Description: 同步档案
     * @date: 2025/3/24 14:10
     * @author: zt
     */
    public void syncTerminalDataInJC(Integer supplierId,String tenantId, String sheetsCode) {
        //获取德高集抄平台大表档案数据
        String resString = DeGaoApi.getTerminalDblist(1,100,sheetsCode);
        JcResult<JcTerminalDb> jcResult = JSON.parseObject(resString, new TypeReference<JcResult<JcTerminalDb>>(){});
        if(jcResult != null && !jcResult.getRows().isEmpty()) {
            //分页设备总数
            Long total = jcResult.getTotal();
            List<JcTerminalDb> jcTerminalDbList = jcResult.getRows();
            if(total>100){
                int size = (int) (total/100 + (total%100>0 ? 1 : 0));
                for (int i = 2; i <= size; i++) {
                    String tempStr = DeGaoApi.getTerminalDblist(i,100,sheetsCode);
                    JcResult<JcTerminalDb> tempRes = JSON.parseObject(tempStr, new TypeReference<JcResult<JcTerminalDb>>(){});
                    if(tempRes != null && !tempRes.getRows().isEmpty()) {
                        jcTerminalDbList.addAll(tempRes.getRows());
                    }
                }
            }

            //处理数据
            if(!jcTerminalDbList.isEmpty()){
                jcTerminalDbList = jcTerminalDbList.stream().filter(item-> StringUtils.isNotEmpty(item.getLocationNb())).collect(Collectors.toList());
                List<String> locationNbList = jcTerminalDbList.stream().map(JcTerminalDb::getLocationNb).collect(Collectors.toList());

                List<Terminals_bf> terminalList =new ArrayList<>();
                //查找数据库中已有的档案
                List<Terminals_bf> oldTerminalList = terminalsService.list(new LambdaQueryWrapper<Terminals_bf>()
                        .in(Terminals_bf::getReMark,locationNbList));
                Map<String,List<Terminals_bf>> locationMap = oldTerminalList.stream().collect(Collectors.groupingBy(Terminals_bf::getReMark));
                jcTerminalDbList.forEach(jcTerminalDb -> {
                    //排除已有的档案数据
                    if(!locationMap.containsKey(jcTerminalDb.getLocationNb())){
                        Terminals_bf terminals_bf = new Terminals_bf();
                        terminals_bf.setTerminalID(jcTerminalDb.getTerminalId());
                        terminals_bf.setSupplierID(supplierId);
                        terminals_bf.setTenant_id(tenantId);
                        terminals_bf.setTerminalName(jcTerminalDb.getTerminalName());
                        terminals_bf.setTerminalMark(1);
                        terminals_bf.setIMEI(jcTerminalDb.getImei());
//                    terminals_bf.setCurrentTotalFlow(jcTerminalDb.getTotalFlow());
//                    terminals_bf.setCurrentReadNumber(jcTerminalDb.getReadNumber());
//                    terminals_bf.setCurrentReverseNumber(jcTerminalDb.getReverseNumber());
//                    terminals_bf.setCurrentInstantNumber(jcTerminalDb.getInstantNumber());
                        terminals_bf.setCurrentPressure(jcTerminalDb.getPressure());
//                    terminals_bf.setCurrentTerminalVol(jcTerminalDb.getTerminalVol());
                        terminals_bf.setCreateDatetime(new Date());
                        terminals_bf.setReMark(jcTerminalDb.getLocationNb());
                        terminals_bf.setUserType("1");
                        terminalList.add(terminals_bf);
                    }
                });
                terminalsService.saveBatch(terminalList);
            }
        }
    }

    /**
     * @Description: 同步大表档案历史数据
     * @date: 2025-03-24 16:18:50
     * @author: zt
     */
    public void syncTerminalDbHistoryDataInJC(Integer supplierId,String tenantId) {
        String startTime = DateUtil.now().substring(0, 10)+" 00:00:00";
        String endTime = DateUtil.now().substring(0, 10)+" 23:59:59";
        String tempStartTime;
        //更改为一个设备请求一次
        List<JcTerminalDbHistoryData> historyDataList = new ArrayList<>();
        List<Terminals_bf> terminalsList = terminalsService.findMasTerminalsByTenantAndSupplierAndLastTime(tenantId, supplierId);
        //过滤符合该条件的档案
        terminalsList = terminalsList.stream().filter(item-> StringUtils.isNotEmpty(item.getReMark()) && item.getReMark().length()==32).collect(Collectors.toList());
        List<Date> lastDateList = terminalsList.stream().map(Terminals_bf::getLastTime).filter(Objects::nonNull).collect(Collectors.toList());
        if(!lastDateList.isEmpty()) {
            Optional<Date> opt = lastDateList.stream().min(Comparator.comparing(Date::getTime));
            tempStartTime = DateUtil.format(opt.get(),"yyyy-MM-dd HH:mm:ss");
        } else {
            tempStartTime = startTime;
        }
        terminalsList.forEach(e->{
            String resString = DeGaoApi.getTerminalDbHistory(1,100,e.getReMark(), tempStartTime,endTime);
            JcResult<JcTerminalDbHistoryData> jcResult = JSON.parseObject(resString, new TypeReference<JcResult<JcTerminalDbHistoryData>>(){});
            if(jcResult != null && !jcResult.getRows().isEmpty()) {
                //分页设备总数
                Long total = jcResult.getTotal();
                List<JcTerminalDbHistoryData> jcTerminalDbHistoryDataList = jcResult.getRows();
                if (total > 100) {
                    int size = (int) (total / 100 + (total % 100 > 0 ? 1 : 0));
                    for (int i = 2; i <= size; i++) {
                        String tempStr = DeGaoApi.getTerminalDbHistory(i, 100, e.getReMark(), tempStartTime, endTime);
                        JcResult<JcTerminalDbHistoryData> tempRes = JSON.parseObject(tempStr, new TypeReference<JcResult<JcTerminalDbHistoryData>>() {
                        });
                        if (tempRes != null && !tempRes.getRows().isEmpty()) {
                            jcTerminalDbHistoryDataList.addAll(tempRes.getRows());
                        }
                    }
                }
                historyDataList.addAll(jcTerminalDbHistoryDataList);
            }
        });
        if(!historyDataList.isEmpty()){
            List<TerminalHistoryData> tempList = new ArrayList<>();
            //整理数据
            historyDataList.forEach(item->{
                TerminalHistoryData temp = new TerminalHistoryData();
                temp.setTerminalName(item.getTerminalName());
                temp.setTerminalID(item.getTerminalId());
                temp.setReadDate(item.getReadDate());
                temp.setTotalFlow(item.getTotalFlow());
                temp.setReadNumber(item.getReadNumber());
                temp.setReverseNumber(item.getReverseNumber());
                temp.setInstantNumber(item.getInstantNumber());
                temp.setPressure(item.getPressure());
                temp.setTerminalVol(item.getTerminalVol());
                temp.setTerminalCSQ(item.getTerminalCsq());
                temp.setInstantVelocity(item.getInstantVelocity());
                temp.setTerminalCSQDescribe(item.getTerminalCsqDescribe());
                temp.setValveState(Integer.valueOf(item.getValveState()));
                tempList.add(temp);
            });
            this.syncToDb(tempList, tempStartTime, endTime);
        }
    }
}
